package cn.edu.hnu.gpg.util;

import org.apache.ibatis.javassist.bytecode.ByteArray;
import org.apache.logging.log4j.core.util.ArrayUtils;
import org.springframework.util.DigestUtils;
import sun.security.provider.MD5;

import java.lang.reflect.Array;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Random;

public class PasswordUtils {

    /**
     * 将明文密码加密。原密码加盐后用 SHA-256 加密
     * @param rawPassword UTF-8 编码的明文密码
     * @param saltBytes 加盐的字节数组
     * @return SHA-256 加密后的 Base64 字符串
     */
    public static String encryptPassword(String rawPassword, byte[] saltBytes) {

        byte[] passwordBytes = rawPassword.getBytes(Charset.defaultCharset());
        byte[] saltedPasswordByte = concat(passwordBytes, saltBytes);
        byte[] passwordHashBytes;
        String passwordHashBase64 = null;

        try {
            MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
            passwordHashBytes = messageDigest.digest(saltedPasswordByte);
            passwordHashBase64 = Base64.getEncoder().encodeToString(passwordHashBytes);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        return passwordHashBase64;
    }

    public static String encryptPassword(String rawPassword, String saltBase64) {
        byte[] saltBytes = Base64.getDecoder().decode(saltBase64);
        return encryptPassword(rawPassword, saltBytes);
    }

    // 连接两个 byte 数组
    private static byte[] concat(byte[] first, byte[] second) {
        byte[] result = new byte[first.length + second.length];
        System.arraycopy(first, 0, result, 0, first.length);
        System.arraycopy(second, 0, result, first.length, second.length);
        return result;
    }

    /**
     * 产生随机序列作为盐值
     * @param random 随机数生成器
     * @param length 随机序列的长度
     * @return 由 {@code random} 生成的随机序列
     */
    public static byte[] generateSalt(Random random, int length) {
        if (length <= 0) {
            throw new IllegalArgumentException("length <= 0");
        }

        byte[] saltBytes = new  byte[length];
        random.nextBytes(saltBytes);

        return saltBytes;
    }
}
